// +FHDR------------------------------------------------------------
//                 Copyright (c) 2022 .
//                       ALL RIGHTS RESERVED
// -----------------------------------------------------------------
// Filename      : apb_agent.sv
// Author        : 
// Created On    : 2022-08-25 17:34
// Last Modified : 
// -----------------------------------------------------------------
// Description:
//
//
// -FHDR------------------------------------------------------------

`ifndef __APB_AGENT_SV__
`define __APB_AGENT_SV__

class apb_agent extends uvm_agent;
	apb_sequencer     sqr;
	apb_driver        drv;
	apb_monitor       mon;
    apb_ready_drv     rdy;

    bit rdy_en;

    virtual apb_interface vif;
    uvm_tlm_analysis_fifo #(apb_transaction) out_fifo;//rm connect out_fifo.blocking_get_export
    `ifdef UTILS_TEST
    uvm_tlm_analysis_fifo #(apb_transaction) drv_out_fifo;
    `endif
	
	`uvm_component_utils(apb_agent)
	
	extern function new(string name = "apb_agent", uvm_component parent=null);
	extern virtual function void build_phase(uvm_phase phase);
	extern virtual function void connect_phase(uvm_phase phase);

endclass

function apb_agent::new(string name = "apb_agent", uvm_component parent=null);
	super.new(name, parent);
endfunction: new

function void apb_agent::build_phase(uvm_phase phase);
	super.build_phase(phase);
    if(!uvm_config_db #(virtual apb_interface)::get(this, "", "vif", vif))begin
		`uvm_fatal("apb_driver", "virtual interface get fatal");
	end
    uvm_config_db#(virtual apb_interface)::set(this, "drv", "vif", vif);
    uvm_config_db#(virtual apb_interface)::set(this, "mon", "vif", vif);
    uvm_config_db#(virtual apb_interface)::set(this, "rdy", "vif", vif);

	if(is_active == UVM_ACTIVE) begin
		sqr = apb_sequencer::type_id::create("sqr", this);
		drv = apb_driver::type_id::create("drv", this);
	end
    if(rdy_en == 1)begin
        rdy = apb_ready_drv::type_id::create("rdy", this);
    end
	mon = apb_monitor::type_id::create("mon", this);
    out_fifo = new("out_fifo", this);
    `ifdef UTILS_TEST
    drv_out_fifo = new("drv_out_fifo", this);
    `endif
endfunction: build_phase

function void apb_agent::connect_phase(uvm_phase phase);
	super.connect_phase(phase);
	if(is_active == UVM_ACTIVE) begin
		drv.seq_item_port.connect(sqr.seq_item_export);
	end
    mon.ap.connect(out_fifo.analysis_export);
    `ifdef UTILS_TEST
    drv.ap.connect(drv_out_fifo.analysis_export);
    `endif
endfunction: connect_phase

`endif
